import { _decorator, AudioClip, AudioSource, Component, EventTouch, instantiate, Label, math, Node, Prefab, sys, tween, UITransform, v2, v3, Vec2 } from 'cc';
import { item } from './item';
const { ccclass, property } = _decorator;

enum moverTouchtype{
         up,
         down,
         left,
         right
}
@ccclass('Game_main')
export class Game_main extends Component {
    
    // UI界面
    @property(Node)
    game_start:Node=null
    @property(Node)
    play_game:Node=null
    @property(Node)
    game_over:Node=null

    // label组件
    @property(Label)
    lvs:Label=null
    @property(Label)
    score:Label=null
    @property(Label)
    bastscore:Label=null
    @property(Label)
    reback:Label=null
    @property(Label)
    successOver:Label=null

    // 背景
    @property(Node)
    palybg:Node=null
    @property(Prefab)
    items:Prefab=null

    // 音频
    @property(AudioClip)
    moveaudio:AudioClip=null
    @property(AudioClip)
    mergesaudio:AudioClip=null

    audio:AudioSource=new AudioSource()

     private UserData:any=null

    // 间隔
    padding:number=5
    itmeWH=0
    itmeparentWH=0
    blockArray:number[][]=[]
    
    // 触摸移动开始结束位置记录
    Startpos = v2(0,0)
    Endpos = v2(0,0)
   
    scores:number=0
    history_bastscores:number=0
     

    start() {
        this.UIinit()
        this.game_start.active=true
        this.addMoveTouch()
       
        console.log(this.blockArray);
        
    }

    addMoveTouch(){
        this.palybg.on(Node.EventType.TOUCH_START,this.Touch_Start,this)
        this.palybg.on(Node.EventType.TOUCH_END,this.Touch_End,this)
    }
    Touch_Start(event:EventTouch){
        this.Startpos=event.getUILocation()
    }
    Touch_End(event:EventTouch){
        this.Endpos=event.getUILocation()
        let endx=this.Endpos.x-this.Startpos.x
        let endy=this.Endpos.y-this.Startpos.y

        let moverpos:moverTouchtype
        // 这里是判断他是横向滑动还是竖向滑动 x轴的值大就是横 y轴值大就是竖
        if(Math.abs(endx)>Math.abs(endy)){
            // 如果是横向 
            moverpos= endx > 0 ?  moverTouchtype.right : moverTouchtype.left
        }else{
            // 否则是竖向
            moverpos= endy > 0 ?  moverTouchtype.up : moverTouchtype.down
        }
        // console.log(moverpos)
        this.doMove(moverpos)
    }

    doMove(moverpos:moverTouchtype){
        switch (moverpos) {
            case moverTouchtype.up:
                console.log("up");
                this.doMoveMergeUp()
                break;
            case moverTouchtype.down:
                console.log("down")
                this.doMoveMergeDown()
                break;
            case moverTouchtype.left:
                console.log("left")
                 this.doMoveMergeRight()
                 
                break;
            case moverTouchtype.right:
                console.log("right")
               this.doMoveMergeLeft()
                break;
          
        }
    }
    
    doMoveMergeUp(){
        // 是否合并
        let merge=false
        // 是否上移动
        let ismove=false
        // 控制列
        for (let j = 0; j < this.UserData.lv; j++) {
          ismove = this.moveUp(j) || ismove
          merge = this.mergeUP(j) || merge
          if(merge){
            ismove=true
          }
            
        }
        this.mergeMoveUp(merge,ismove)
    }
    doMoveMergeDown(){
        // 是否合并
        let merge=false
        // 是否上移动
        let ismove=false
        // 控制列
        for (let j = 0; j < this.UserData.lv; j++) {
          ismove = this.moveDown(j) || ismove
          merge = this.mergeDown(j) || merge
          if(merge){
            ismove=true
          }
        //   if(merge){
        //     this.UpdataView()
        // }
            
        }
        this.mergeMoveUp(merge,ismove)
    }
    doMoveMergeRight(){
        // 是否合并
        let merge=false
        // 是否上移动
        let ismove=false
        // 控制列
        for (let i = 0; i < this.UserData.lv; i++) {
          ismove = this.moveRight(i) || ismove
          merge = this.mergeRight(i) || merge
          if(merge){
            ismove=true
          }
        //   if(merge){
        //     this.UpdataView()
        //   }
            
        }
        this.mergeMoveUp(merge,ismove)

    }
    doMoveMergeLeft(){
        // 是否合并
        let merge=false
        // 是否上移动
        let ismove=false
        // 控制列
        for (let i = 0; i < this.UserData.lv; i++) {
          ismove = this.moveLeft(i) || ismove
          merge = this.mergeLeft(i) || merge
          if(merge){
            ismove=true
          }
        //   if(merge){
        //     this.UpdataView()
        //   }  
        }
        this.mergeMoveUp(merge,ismove)
    }

    // 向上移动
    moveUp(j:number):boolean{
        let ismove=false
        // 控制行
        for (let i = 0; i < this.UserData.lv; i++) {
            if(this.blockArray[i][j]==0){
                // 这里i+1是 表示的是第二行 
                for (let k = i+1; k < this.UserData.lv; k++) {
                    if(this.blockArray[k][j] != 0){
                        this.blockArray[i][j]=this.blockArray[k][j]
                        this.blockArray[k][j]=0
                        ismove=true
                        break 
                    }
                }
            } 
        }
        return ismove
    }
    // 向下移动
    moveDown(j:number):boolean{
        let ismove=false
        // 控制行
        for (let i = this.UserData.lv-1; i >= 0 ; i--) {
            if(this.blockArray[i][j]==0){
                // 这里i+1是 表示的是第二行 
                for (let k = i-1; k >=0; k--) {
                    if(this.blockArray[k][j] != 0){
                        this.blockArray[i][j]=this.blockArray[k][j]
                        this.blockArray[k][j]=0
                        ismove=true
                        break 
                    }
                }
            } 
        }
        return ismove
    }
    // 左移动
    moveLeft(i:number):boolean{
        let ismove=false
        // 控制行
        for (let j = this.UserData.lv-1; j >= 0 ; j--) {
            if(this.blockArray[i][j]==0){
                // 这里i+1是 表示的是第二行 
                for (let k = j-1; k >=0; k--) {
                    if(this.blockArray[i][k] != 0){
                        console.log(this.blockArray[i][k]);
                        
                        this.blockArray[i][j]=this.blockArray[i][k]
                        this.blockArray[i][k]=0
                        ismove=true
                        break 
                    }
                }
            } 
        }
        return ismove
    }
    // 向右移动逻辑
    moveRight(i:number):boolean{
        let ismove=false
        // 控制行
        for (let j = 0; j <this.UserData.lv ; j++) {
            if(this.blockArray[i][j]==0){
                // 这里i+1是 表示的是第二行 
                for (let k = j+1; k < this.UserData.lv; k++) {
                    if(this.blockArray[i][k] != 0){
                        this.blockArray[i][j]=this.blockArray[i][k]
                        this.blockArray[i][k]=0
                        ismove=true
                        break 
                    } 
                }  
            } 
        }
        console.log(this.blockArray);
        return ismove
    }
    //  上合并逻辑
    mergeUP(j:number):boolean{
       let merge=false
        // 再次循环行
       for (let i = 0; i < this.UserData.lv-1; i++) {
            if(this.blockArray[i][j]==this.blockArray[i+1][j]&& this.blockArray[i][j]!= 0){
                this.blockArray[i][j]*=2
                this.blockArray[i+1][j]=0
                this.scores += this.blockArray[i][j]
                merge=true
                // if(merge){
                //     this.UpdataView()
                // }
               
            }   
       }
       this.moveUp(j)
       return merge
    }
     //  下合并逻辑
     mergeDown(j:number):boolean{
        let merge=false
         // 再次循环行
        for (let i = this.UserData.lv-1; i > 0 ; i--) {
             if(this.blockArray[i][j]==this.blockArray[i-1][j] && this.blockArray[i][j]!= 0){
                 this.blockArray[i][j]*=2
                 this.blockArray[i-1][j]=0
                 this.scores += this.blockArray[i][j]
                // console.log(this.UserData.score);
                
                 merge=true
                //  if(merge){
                //     this.UpdataView()
                // }
             }   
        }
        this.moveDown(j)
        return merge
     }
    //  左合并
     mergeLeft(i:number):boolean{
        let merge=false
         // 再次循环行
        for (let j = this.UserData.lv-1; j > 0 ; j--) {
             if(this.blockArray[i][j]==this.blockArray[i][j-1]&& this.blockArray[i][j]!= 0){
                 this.blockArray[i][j]*=2
                 this.blockArray[i][j-1]=0
                 this.scores += this.blockArray[i][j]
                // console.log(this.UserData.score);
                
                 merge=true
                //  if(merge){
                //     this.UpdataView()
                // }
             }   
        }
        // console.log(this.blockArray);
        // console.log(this.blockArray[0][0]);
        // console.log(this.blockArray);
        this.moveLeft(i)
        return merge
     }
     
    //  右合并
    mergeRight(i:number):boolean{
        let merge=false
         // 再次循环行
        for (let j = 0; j < this.UserData.lv-1; j++) {
             if(this.blockArray[i][j]==this.blockArray[i][j+1]&& this.blockArray[i][j]!= 0){
                 this.blockArray[i][j]*=2
                 this.blockArray[i][j+1]=0
                 this.scores += this.blockArray[i][j]
                 merge=true
                //  if(merge){
                //      this.UpdataView()
                //  }

             }   
        }
        this.moveRight(i)
        return merge
     }
 /**
       * 
       * @param merge 合并
       * @param  移动
       * @returns 
       */
    mergeMoveUp(merge,ismove){
        if(!ismove){
            return
        }
        
        if(merge){
            this.audio.playOneShot(this.mergesaudio,0.1)
        }else{
            this.audio.playOneShot(this.moveaudio)
        }
        
        if(merge){
            this.UpdataView()
        }
        this.audio.playOneShot(this.mergesaudio)
        
        this.addblock()
        this.randomblock()
        this.checkOver()
    }
    
    update(deltaTime: number) {
        
    }


    public checkOver(){
        if(this.GameSuccess()){
        this.game_over.active=true
        this.history_bastscores=this.scores
        this.successOver.string=this.scores.toString()
        }
        if(this.Overgames()){
        this.game_over.active=true
        this.history_bastscores=this.scores
        this.successOver.string=this.scores.toString()
        }
     }
     GameSuccess():boolean{
         for (let i = 0; i <this.UserData.lv; i++) {
             for (let j = 0; j < this.UserData.lv; j++) {
               if(this.blockArray[i][j]==2048){
                 return true
               } 
                 
             }
         }
         return false
     }

     Overgames(){
        // 判断有没有空格子
        for (let i = 0; i <this.UserData.lv; i++) {
            for (let j = 0; j < this.UserData.lv; j++) {
              if(this.blockArray[i][j]==0){
                return false
              }   
            }
        }

        // 判断两个相邻的格子数字是否相等
        for (let i = 0; i <this.UserData.lv; i++) {
            for (let j = 0; j < this.UserData.lv - 1; j++) {
              if(this.blockArray[i][j]==this.blockArray[i][j+1]){
                return false
              }   
            }
        }

        for (let i = 0; i <this.UserData.lv-1; i++) {
            for (let j = 0; j < this.UserData.lv ; j++) {
              if(this.blockArray[j][i]==this.blockArray[j][i+1]){
                return false
              }   
            }
        }

        return true
     }

    // 初始化
    init(){
        this.getUserData()
        this.UpdataView()
        this.blockinit()
        this.addblock()
        this.randomblock()  
    }
    // 获取用户信息
    getUserData(){
        this.UserData = JSON.parse(sys.localStorage.getItem('User'))
        if(this.UserData==null){
            this.UserData={
                lv:5,
                score:0,
                bastScore:0,
                reback:3
            }
        }
    }
    // 设置信息
    setUserData(){
       sys.localStorage.setItem('User',JSON.stringify(this.UserData))
    }

    // 更新视图
    UpdataView(){
        let lv=this.UserData.lv
        this.lvs.string=this.UserData.lv+"X"+this.UserData.lv
        this.UserData.score=this.scores
        this.score.string=this.UserData.score.toString()
        
        this.UserData.bastScore= this.scores > this.history_bastscores  ? this.scores : this.history_bastscores
        this.bastscore.string=this.UserData.bastScore+''
        this.reback.string="撤销("+this.UserData.reback+")"
        this.itmeparentWH = this.palybg.getComponent(UITransform).contentSize.width
        this.itmeWH=Math.round((this.itmeparentWH -(lv+1)*this.padding)/lv)
       
    }

    // 初始UI界面
    UIinit(){
      this.game_start.active=false
      this.play_game.active=false
      this.game_over.active=false
    }


    // 初始化棋盘
    /**
     * 1.初始化棋盘
     * 2.给棋盘创建盒子
     * 3.给棋盘里的方块定位
     * @param lv  棋盘几乘几
     */
    blockinit(){
        for (let i = 0; i <this.UserData.lv ; i++) {
            this.blockArray[i]=[]
            for (let j = 0; j <this.UserData.lv ; j++) {
               this.blockArray[i][j] = 0
            } 
        }
        // console.log(this.blockArray);
        
    }
    
    addblock(){
        for (let i = 0; i <this.UserData.lv ; i++) {
            for (let j = 0; j <this.UserData.lv ; j++) {
               // 创建格子
                this.crateblock(i,j,this.blockArray[i][j])
            } 
         }
    }
    //  生成方块
    crateblock(i:number,j:number,num:number,is?:boolean){
        let items=instantiate(this.items)
        //  获取item脚本
        let itemjs= items.getComponent(item)
        if(itemjs){
        //   使用item方法
            itemjs.iteminit(num)
        }
        items.parent=this.palybg
        let  itemTF=items.getComponent(UITransform)
        //    设置位置
        itemTF.setContentSize(this.itmeWH,this.itmeWH)
        let  itemspos=this.getPosXYblock(i,j)
        // console.log(-itemspos.x,-itemspos.y);
        items.setPosition(itemspos.x,-itemspos.y)
        if(is){
            items.scale = v3(0,0,0)
            tween(items).to(0.5,{scale: v3(1,1,1)},{easing:"quadInOut"}).start()
        }
    }
    // 确定定位
    getPosXYblock(i:number,j:number):Vec2{
        let  posWH=v2(-this.itmeparentWH/2+this.itmeWH/2+this.padding,-this.itmeparentWH/2+this.itmeWH/2+this.padding)
        let  posX=posWH.x+(this.itmeWH+this.padding)*j
        let  posY=posWH.y+(this.itmeWH+this.padding)*i
        // let  posX=(this.itmeWH+this.padding)*j
        // let  posY=(this.itmeWH+this.padding)*i
        // console.log(posX,posY);
        
        return v2(posX,posY)
    }
    // 获取空数组位置
    getEmptyblock(){
       let  getArray=[]
        for (let i = 0; i < this.UserData.lv; i++) {
          for (let j = 0; j < this.UserData.lv; j++) {
            if(this.blockArray[i][j]==0){
                getArray.push({x:i,y:j})
            } 
          }   
        }
        return getArray
    }
    // 随机出方块
    randomblock(){
        let  Arraypos=this.getEmptyblock()
        if(Arraypos.length>0){
            let  randPos = Arraypos[Math.floor(Math.random()*Arraypos.length)]
            this.blockArray[randPos.x][randPos.y]=math.random() > 0.8 ? 8 : 2
            this.crateblock(randPos.x,randPos.y,this.blockArray[randPos.x][randPos.y],true)
         }
        //  console.log(this.blockArray);
         
        // this.crateblock(randPos.x,randPos.y,this.blockArray[randPos.x][randPos.y])
    }




    // 开始游戏按钮
    game_start_Btn(){
        this.UIinit()
        this.play_game.active=true
        this.init()    
    }
      
    // 重新开始按钮
    play_re_Btn(){
        this.scores=0
    }

    // 撤销按钮
    play_back_Btn(){
   
    }
    // 返回菜单按钮
    play_rehome_Btn(){
        this.UIinit()
        this.game_start.active=true
        this.scores=0
    }
    
    // 再来一局按钮
    over_re_Btn(){
        this.scores=0
    }

    // 返回主页按钮
    over_home_Btn(){
        this.UIinit()
        this.game_start.active=true
        this.scores=0
    }


}







